package cn.ldf.keepaccounts.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import cn.ldf.keepaccounts.dao.MembersDao;
import cn.ldf.keepaccounts.entity.event.MembersEvent;
import cn.ldf.keepaccounts.entity.pojo.Members;
import cn.ldf.keepaccounts.entity.pojo.Users;
import cn.ldf.keepaccounts.entity.vo.MembersAvatarVO;
import cn.ldf.keepaccounts.enums.WsOptionEnum;
import cn.ldf.keepaccounts.service.MembersService;
import cn.ldf.keepaccounts.service.UsersService;
import cn.ldf.keepaccounts.utils.ExceptionUtil;
import cn.ldf.keepaccounts.utils.StreamUtil;
import cn.ldf.keepaccounts.websocket.RoomsWebsocket;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 房间成员表(Members)表服务实现类
 *
 * @author 清峰
 * @since 2025-02-17 10:12:34
 */
@Service("membersService")
public class MembersServiceImpl extends ServiceImpl<MembersDao, Members> implements MembersService {

    @Resource
    private UsersService usersService;
    @Resource
    private MembersDao membersDao;

    @Override
    public Members addMembers(Members members) {
        members.setJoinTime(new Date());
        WsOptionEnum wsOption;
        //检查成员是否加入结算过
        Members membersOld = this.lambdaQuery().eq(Members::getRoomId, members.getRoomId()).eq(Members::getOpenId, members.getOpenId()).one();
        if (ObjUtil.isNotEmpty(membersOld)) {
            if (membersOld.isSettled()) {
                members.setId(membersOld.getId());
                members.setSettled(false);
                this.updateById(members);
            } else {
                //未结算再次加入房间
                return members;
            }
            wsOption = WsOptionEnum.UPDATE_MEMBERS;
        } else {
            this.save(members);
            wsOption = WsOptionEnum.ADD_GAME_RECORDS;
        }
        //推送ws消息
        Users users = usersService.getByOpenId(members.getOpenId());
        MembersEvent membersEvent = MembersEvent.builder().wsOptionEnum(wsOption).membersList(Collections.singletonList(members)).users(users).build();
        RoomsWebsocket.sendInfo(membersEvent, members.getRoomId());
        return members;
    }

    @Override
    public Members updateMembersNickname(Members members) {
        String roomId = members.getRoomId();
        String openId = members.getOpenId();
        String nickname = members.getNickname();
        Members membersOld = getByRoomIdAndOpenId(roomId, openId);
        membersOld.setNickname(nickname);
        boolean update = this.lambdaUpdate()
                .eq(Members::getRoomId, roomId)
                .eq(Members::getOpenId, openId)
                .set(Members::getNickname, nickname).update();
        if (update) {
            //推送ws消息
            Users users = usersService.getByOpenId(members.getOpenId());
            MembersEvent membersEvent = MembersEvent.builder().wsOptionEnum(WsOptionEnum.UPDATE_MEMBERS).membersList(Collections.singletonList(membersOld)).users(users).build();
            RoomsWebsocket.sendInfo(membersEvent, members.getRoomId());
        }
        return members;
    }

    @Override
    public List<Members> getAllByRoomId(String roomId) {
        return this.lambdaQuery().eq(Members::getRoomId, roomId).list();
    }

    @Override
    public List<Members> getNoSettledByRoomId(String roomId) {
        return this.lambdaQuery().eq(Members::getRoomId, roomId).eq(Members::isSettled, false).list();
    }

    @Override
    public Members getByRoomIdAndOpenId(String roomId, String openId) {
        Members members = this.lambdaQuery().eq(Members::getRoomId, roomId).eq(Members::getOpenId, openId).one();
        ExceptionUtil.throwMsg(() -> ObjUtil.isEmpty(members), "房间成员不存在");
        return this.lambdaQuery().eq(Members::getRoomId, roomId).eq(Members::getOpenId, openId).one();
    }

    @Override
    public Boolean isSettledByRoomIdAndOpenId(String roomId, String openId) {
        Members members = getByRoomIdAndOpenId(roomId, openId);
        return members.isSettled();
    }

    @Override
    public Boolean updateSettledById(Long id) {
        return this.lambdaUpdate().eq(Members::getId, id).set(Members::isSettled, true).update();
    }

    @Override
    public List<MembersAvatarVO> getAvatarByRoomId(String roomId) {
        List<Members> membersList = this.lambdaQuery().eq(Members::getRoomId, roomId).list();
        if (membersList.isEmpty()) {
            return Collections.emptyList();
        }
        List<String> openIdList = membersList.stream().map(Members::getOpenId).toList();
        List<Users> usersList = usersService.getListAvatarByOpenIds(openIdList);
        //封装数据
        List<MembersAvatarVO> membersAvatarVOList = ListUtil.list(false);
        for (Users users : usersList) {
            String openId = users.getOpenId();
            String contentType = users.getContentType();
            byte[] avatar = users.getAvatar();
            String byteToBase64 = ObjUtil.isNotEmpty(avatar) ? StreamUtil.byteToBase64(avatar) : null;
            Members members = membersList.stream().filter(x -> x.getOpenId().equals(openId)).findFirst().orElse(null);
            MembersAvatarVO membersAvatarVO = MembersAvatarVO.builder().roomId(roomId).openId(openId).avatarBase64(byteToBase64).contentType(contentType)
                    .nickname(ObjUtil.isNotEmpty(members) ? Objects.requireNonNull(members).getNickname() : null)
                    .settled(ObjUtil.isNotEmpty(members) && Objects.requireNonNull(members).isSettled())
                    .score(ObjUtil.isNotEmpty(members) ? Objects.requireNonNull(members).getScore() : 0).build();
            membersAvatarVOList.add(membersAvatarVO);
        }
        return membersAvatarVOList;
    }

    @Override
    public List<MembersAvatarVO> getMembersAvatarListByRoomIds(List<String> roomIds) {
        return membersDao.getMembersAvatarListByRoomIds(roomIds);
    }

    @Override
    public List<Members> getListByRoomIds(List<String> roomIds) {
        return this.lambdaQuery().in(Members::getRoomId, roomIds).list();
    }

    @Override
    public List<MembersAvatarVO> getListMembersByIsWinn(String roomId, String currentOpenId) {
        List<MembersAvatarVO> membersAvatarVOList = this.getAvatarByRoomId(roomId);
        if (membersAvatarVOList.isEmpty()) {
            return membersAvatarVOList;
        }
        List<MembersAvatarVO> currentMembersAvatarVOS = membersAvatarVOList.stream().filter(x -> x.getOpenId().equals(currentOpenId)).toList();
        if (currentMembersAvatarVOS.isEmpty()) {
            return membersAvatarVOList;
        }
        List<MembersAvatarVO> otherMembersAvatarVOS;
        if (currentMembersAvatarVOS.get(0).getScore() >= 0) {
            otherMembersAvatarVOS = membersAvatarVOList.stream().filter(x -> !x.getOpenId().equals(currentOpenId) && x.getScore() < 0).toList();
        } else {
            otherMembersAvatarVOS = membersAvatarVOList.stream().filter(x -> !x.getOpenId().equals(currentOpenId) && x.getScore() > 0).toList();
        }
        List<MembersAvatarVO> list = ListUtil.list(true);
        list.addAll(currentMembersAvatarVOS);
        list.addAll(otherMembersAvatarVOS);
        return list;
    }
}

